<!DOCTYPE html>
<html>
<head>
<title>Prism and Mirror Diagram</title>
<style>
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
  }
  canvas {
    border: 1px solid #ccc;
    background-color: #fff;
  }
</style>
</head>
<body>
<canvas id="physicsCanvas" width="600" height="480"></canvas>
<script>
  const canvas = document.getElementById('physicsCanvas');
  const ctx = canvas.getContext('2d');

  // General style settings
  ctx.strokeStyle = 'black';
  ctx.fillStyle = 'black';
  ctx.lineWidth = 2;

  // --- 1. Draw the Prism ---
  const prismApex = { x: 180, y: 120 };
  const prismBaseL = { x: 150, y: 340 };
  const prismBaseR = { x: 210, y: 340 };

  // Save context state before clipping for the fill pattern
  ctx.save();

  // Create prism path
  ctx.beginPath();
  ctx.moveTo(prismApex.x, prismApex.y);
  ctx.lineTo(prismBaseL.x, prismBaseL.y);
  ctx.lineTo(prismBaseR.x, prismBaseR.y);
  ctx.closePath();

  // Clip the drawing area to the prism's shape
  ctx.clip();

  // Draw the diagonal fill lines
  ctx.lineWidth = 1.5;
  for (let i = -20; i < 350; i += 10) {
    ctx.beginPath();
    ctx.moveTo(prismBaseL.x + i, prismBaseL.y);
    ctx.lineTo(prismBaseR.x + i + 60, prismApex.y);
    ctx.stroke();
  }

  // Restore the context to remove the clipping mask
  ctx.restore();

  // Draw the outline of the prism
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.moveTo(prismApex.x, prismApex.y);
  ctx.lineTo(prismBaseL.x, prismBaseL.y);
  ctx.lineTo(prismBaseR.x, prismBaseR.y);
  ctx.closePath();
  ctx.stroke();
  
  // Draw the apex angle mark
  ctx.beginPath();
  ctx.arc(prismApex.x, prismApex.y + 20, 18, -Math.PI * 0.7, -Math.PI * 0.3);
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(prismApex.x + 10, prismApex.y + 10, 2, 0, 2 * Math.PI);
  ctx.stroke();

  // Add the "prism" label
  ctx.font = 'bold 24px sans-serif';
  ctx.textAlign = 'center';
  ctx.fillText('prism', prismApex.x, prismApex.y - 20);

  // --- 2. Draw the Mirror ---
  const mirrorX = 480;
  // Draw the main vertical line for the mirror
  ctx.beginPath();
  ctx.moveTo(mirrorX, 120);
  ctx.lineTo(mirrorX, 400);
  ctx.stroke();

  // Draw the hash marks on the back of the mirror
  ctx.lineWidth = 1;
  for (let y = 130; y < 400; y += 15) {
    ctx.beginPath();
    ctx.moveTo(mirrorX, y);
    ctx.lineTo(mirrorX + 10, y + 10);
    ctx.stroke();
  }
  ctx.lineWidth = 2;

  // Add the "mirror" label
  ctx.fillText('mirror', mirrorX, 100);

  // --- 3. Draw the Light Ray Path ---
  // Incoming ray
  const rayEnterY = 240;
  ctx.beginPath();
  ctx.moveTo(50, rayEnterY);
  ctx.lineTo(160, rayEnterY); // Point on the left face of the prism
  ctx.stroke();
  // Arrowhead for incoming ray
  ctx.beginPath();
  ctx.moveTo(160, rayEnterY);
  ctx.lineTo(150, rayEnterY - 5);
  ctx.moveTo(160, rayEnterY);
  ctx.lineTo(150, rayEnterY + 5);
  ctx.stroke();

  // Ray from prism to mirror
  const rayExitPoint = { x: 195, y: 270 };
  const rayHitPoint = { x: mirrorX, y: 330 };
  ctx.beginPath();
  ctx.moveTo(rayExitPoint.x, rayExitPoint.y);
  ctx.lineTo(rayHitPoint.x, rayHitPoint.y);
  ctx.stroke();

  // Reflected ray
  const reflectedEndPoint = { x: 380, y: 380 };
  ctx.beginPath();
  ctx.moveTo(rayHitPoint.x, rayHitPoint.y);
  ctx.lineTo(reflectedEndPoint.x, reflectedEndPoint.y);
  ctx.stroke();
  // Arrowhead for reflected ray
  ctx.beginPath();
  ctx.moveTo(reflectedEndPoint.x, reflectedEndPoint.y);
  ctx.lineTo(reflectedEndPoint.x + 12, reflectedEndPoint.y - 6);
  ctx.moveTo(reflectedEndPoint.x, reflectedEndPoint.y);
  ctx.lineTo(reflectedEndPoint.x + 6, reflectedEndPoint.y + 9);
  ctx.stroke();


  // --- 4. Draw the Dashed Reference Line ---
  ctx.save();
  ctx.setLineDash([8, 6]);
  ctx.lineWidth = 1.5;
  ctx.beginPath();
  ctx.moveTo(300, rayHitPoint.y);
  ctx.lineTo(rayHitPoint.x, rayHitPoint.y);
  ctx.stroke();
  ctx.restore();

  // --- 5. Draw the Figure Label ---
  ctx.font = 'bold 20px sans-serif';
  ctx.fillText('Fig. 1.1', 320, 450);

</script>
</body>
</html>